function Panels ( name, attrs )
{
	this.templates = panels_templates.clone();
	if ( ! attrs ) attrs = {};
	if ( attrs.get ( 'templates' ) ) this.templates.inherits ( attrs.get ( 'templates' ), true );

	this.head_left = attrs.get ( 'head_left', 'out' );
	this.head_right = attrs.get ( 'head_right', 'in' );
	this._panels_name = ( name ) ? name : 'panel-' + Panels._instances.count ();
	this._from_div = this._panels_name + '_panels_not_in_group';		//left panel id
	this._tgt_div  = this._panels_name + '_panels_in_group';		//right panel id;		
		
	this.cbacks = {
			'list_done' : null,
			'on_change' : null,
			'done'	    : null
			}; 
	Panels._instances [ name ] = this;
};

Panels._instances = {};

Panels.prototype._mk_opts = function ( v, sel, out )
{	
	v [ 'side' ] = sel;
	v [ '_panels_name' ] = this._panels_name;
	var tmpl = String.formatDict ( this.templates [  'panels-sel-box-option' ], v );
	if ( ! out ) return tmpl;
	$( sel ).innerHTML += tmpl;
};

Panels.prototype.manage_groups = function ( gl, gr )
{
	if ( ! $( this._panels_name ) ) return;
	var self = this;

	function _req_data ()
	{
		var out = new String.buffer ();
		group.iterate ( function ( v, k )
				{
					out.add ( self._mk_opts ( v, sel_id ) );
				} );
				$( sel_id , out );
		if ( self.cbacks.list_done ) self.cbacks.list_done ();
	};

	//$( this._panels_name , this.templates [ 'panels-manage-group' ] );

	var sel_id = this._from_div; 
	var group = gl;
	_req_data ();
	sel_id = this._tgt_div; 
	group = gr;
	_req_data ();
};

Panels.prototype._parse_opts_div = function ( el )
{
	var nt, data = {};
	//nt = ( el.nodeType == 1 ) ? true : false;
	nt = liwe.dom.has_class ( el, 'panels-sel-unselected' );
	if ( ! nt ) return data; 
	var prefix = this._panels_name.length + 1;
	data [ 'id' ] = el.id.substring ( prefix );
	data [ 'name' ] = el.getElementsByTagName ( 'div' ) [ 0 ].innerHTML;
	data [ 'title' ] = el.title;
	return data;
};

Panels.prototype.swap_side = function ( id, sel_id, tgt )
{
	var self = this;

	function _loop_options ()
	{
		var o, curr, sel = curr_sel.getElementsByTagName ( 'div' );
		var el_class, tmp = [];
		for ( o = 0; o < sel.length; o ++ )
		{
			curr = self._parse_opts_div ( sel [ o ] );
			if ( curr.count () < 1 ) continue;
			tmp [ curr.name ] = curr;
		} 
		return tmp;	
	};

	if ( ! tgt ) tgt = ( sel_id == this._from_div ) ? this._tgt_div : this._from_div ;
	var from_sel = $( sel_id );
	var tgt_sel = $( tgt );
	var selected, curr_opt, curr_sel, opts = [], move = [], opts_keys = [], ordered = new String.buffer (); 
	var pan_opt_id = this._panels_name + '_' + id;
	selected = $( pan_opt_id );
	curr_opt = this._parse_opts_div ( selected ); 
	move [ curr_opt.name ] = curr_opt; 
	liwe.dom.remove_element ( $( pan_opt_id ), from_sel );

	curr_sel = tgt_sel;
	opts = _loop_options ();

	opts.inherits ( move );
	opts_keys = opts.keys ();
	opts_keys.sort ();

	opts_keys.iterate ( function ( v, o ) 
			{
				if ( v == 'parent' ) return;
				ordered.add ( self._mk_opts ( opts [ v ], tgt ) );
			} );
	$( tgt, ordered );
	if ( this.cbacks.on_change ) this.cbacks.on_change ( pan_opt_id );
};

Panels.prototype.return_groups = function ()
{
	var self = this;
	var sel = this._from_div;
	var data = {};
	function _make_lst ()
	{
		var opts = $( sel ).getElementsByTagName ( 'div' );
		var c, tmp, ids_lst = [];		
		for ( c = 0; c < opts.length; c++ )
		{
			tmp = self._parse_opts_div ( opts [ c ] );
			if ( tmp.count () < 1 ) continue ;
			ids_lst.push ( tmp.id );
		}
		if ( ids_lst.length < 1 ) return '';
		return ids_lst.join ( '|' );
	};
	data [ 'group_left' ] = _make_lst ();
	sel = this._tgt_div;
	data [ 'group_right' ] = _make_lst ();
	if ( this.cbacks.done ) 
	{
		this.cbacks.done ( data );
		return;
	}
	return data;
};
Panels._get_instance = function ( name )
{
	return Panels._instances [ name ];
};
Panels.init = function  ( name, dest_div )
{
	var p = Panels._get_instance ( name );
	var layout =  String.formatDict ( p.templates [ 'panels-manage-group' ], p );
	if ( ! dest_div ) return layout;
	$( dest_div , layout ); 
};

Panels.populate = function ( name , group_left, group_right )
{
	var p = Panels._get_instance ( name );
	p.manage_groups ( group_left, group_right );
};

Panels.swap = function ( name, id, sel_id, tgt )
{
	var p = Panels._get_instance ( name );
	p.swap_side ( id, sel_id, tgt ); 
};

Panels.return_groups = function ( name )
{
	var p = Panels._get_instance ( name );
	var gr = p.return_groups ();
	if ( gr ) return gr;
};
